using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tool;

namespace SerialPortCommunicationProject.Tools
{
    public class SerialPortCommunication : ICommunication
    {
        private SerialPort serialPort;

        private byte[] sendBuffer;
        private byte[] receiveBuffer;

        public byte[] SendBuffer { get => sendBuffer;  }
        public byte[] ReceiveBuffer { get => receiveBuffer; }

        public SerialPortCommunication(string portName, int baudRate, int dataBits, Parity parity, StopBits stopBits)
        {
            serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
            receiveBuffer = new byte[100];
        }

        public bool IsOpen { get; set; }
        

        public bool Close()
        {
            if (serialPort != null)
            {
                serialPort.DataReceived -= DataReceived;
            }
            serialPort?.Close();
            serialPort?.Dispose();
            IsOpen = false;
            return false;
        }

        public void DataReceive()
        {
            if (serialPort?.IsOpen == true)
            {
                serialPort.DataReceived += DataReceived;
            }
        }

        public bool Open()
        {
            if (serialPort == null)
            {
                IsOpen = false;
                return false;
            }
            try 
            {
                serialPort.Open();

                DataReceive();
                IsOpen = true;
                return true;
            } catch(Exception ex)
            {
                IsOpen = false;
                return false;
            }
         }

        public void Send(byte[] sendBuffer)
        {
            if (IsOpen)
            {
                serialPort.Write(sendBuffer, 0, sendBuffer.Length);
                this.sendBuffer = sendBuffer;
                ViewModelHelper.GenerateDataRecord(this, Status.Send);
            }
        }

        private void DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (serialPort?.IsOpen==true)
            {
                int bufferSize = serialPort.BytesToRead;
                byte[] buffer = new byte[bufferSize]; 
                serialPort.Read(buffer, 0, bufferSize);
                receiveBuffer = buffer;

                ViewModelHelper.GenerateDataRecord(this, Status.Receive);
            }
        }

        public void Dispose()
        {
            serialPort.Dispose();
            serialPort = null;
        }
    }
}
